package com.woniu.inlet.listen;

import com.alibaba.fastjson.JSON;
import com.rabbitmq.client.Channel;
import com.woniu.adapter.SellRateAdapter;
import com.woniu.inlet.vo.ConfirmCurrentSellOrder;
import com.woniu.outlet.client.OrderMessage;
import com.woniu.outlet.client.UpdateOrderStatus;
import com.woniu.outlet.mysql.ReceivedMsgOrderSellCurrentPayDao;
import com.woniu.outlet.mysql.po.ReceivedMsgOrderSellCurrentPayMySQL;
import com.woniu.outlet.mysql.po.SellRateMySQL;
import com.woniu.service.UserDetailService;
import com.woniu.service.bean.AddEarnings;
import com.woniu.service.bean.AddSellRecord;
import com.woniu.service.domain.UserDetail;
import com.woniu.util.AppUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.support.AmqpHeaders;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.handler.annotation.Header;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.LinkedMultiValueMap;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.List;

/**
 * 获取活期产品的卖出监听
 */
@Slf4j
@RabbitListener(queues = "order_sell_current_pay")
@Component
public class CurrentSellOrderListener {

    @Autowired
    private ReceivedMsgOrderSellCurrentPayDao receivedMsgOrderSellCurrentPayDao;
    @Autowired
    private OrderMessage orderMessage;
    @Autowired
    private UpdateOrderStatus updateOrderStatus;
    @Autowired
    private SellRateAdapter sellRateAdapter;
    @Autowired
    private UserDetailService userDetailService;

    @Transactional // 抛出异常，事务回滚。
    @RabbitHandler
    public void handle(String message, Channel channel, @Header(AmqpHeaders.DELIVERY_TAG) long tag) throws IOException {
        log.debug("开始监听队列");
        String[] strings = message.split("!");
        log.debug("消息内容", strings);
        if (strings.length < 2) {
            channel.basicReject(tag, false);
            throw new RuntimeException("接收到的消息内容格式错误");
        }

        // 消息的第一部分是：消息在【可靠消息服务】那边的消息表中的ID（唯一）。
        String messageIdString = strings[0];
        Integer messageId = Integer.parseInt(messageIdString);

        // 消息的第二部分是：订单模块发送过来的具体消息 。
        String substring = strings[1];

        try {
            // 1. 判断是否是重复消息：insert into 去重表
            receivedMsgOrderSellCurrentPayDao.insert(new ReceivedMsgOrderSellCurrentPayMySQL(null, messageId));
        } catch (RuntimeException e) {
            log.debug("该消息重复");
            // 2. 拒绝消息。要求 RabbitMQ 从队列中删除。
            channel.basicReject(tag, false);
            return;
        }

        try {
            log.debug("执行本地业物逻辑");
            LinkedMultiValueMap<String, String> object = JSON.parseObject(substring, LinkedMultiValueMap.class);
            String sid = "";
            for (String id : object.keySet()) {
                if (id.equals("sell")) {
                    List<String> sells = object.get(id);
                    sid = sells.get(0);
                }
            }
            for (String id : object.keySet()) {
                if (id.equals("sell")) {
                    continue;
                }
                List<String> strings1 = object.get(id);
                log.debug("该用户的产品卖出信息：{}", strings1);
                String join = StringUtils.join(strings1.toArray(), "/");
                //第1个是codeId,第2个是名字，第3个是userId，第4个是持有天数，第5个是本金+收益，第6个是产品类型
                String[] split = join.split("/");
                //计算手续费利率
                SellRateMySQL sellRateByDay = sellRateAdapter.getSellRateByDay(Integer.parseInt(split[3]));
                //计算手续费
                BigDecimal cost = new BigDecimal(0);
                BigDecimal dealMoney = new BigDecimal(split[5]);//本金加收益
                cost = (dealMoney.multiply(BigDecimal.valueOf(sellRateByDay.getRate()))).divide(new BigDecimal(1), 2, BigDecimal.ROUND_DOWN);
                log.debug("手续费为{}", cost);
                //计算扣除手续费之后的金额
                BigDecimal sellAmount = new BigDecimal(0);
                sellAmount = dealMoney.subtract(cost);
                //openfeign通知订单模块
                ConfirmCurrentSellOrder conf = new ConfirmCurrentSellOrder();
                conf.setId(Long.parseLong(sid));
                conf.setSellAmount(sellAmount);
                conf.setSellCost(cost);
                updateOrderStatus.confirmCurrentSellOrder(conf);
                //给用户余额加钱
                //根据用户id查询用户
                UserDetail user = userDetailService.getMoneyByUserId(Integer.valueOf(split[2]));
                UserDetail userDetail = new UserDetail();
                userDetail.setUserId(user.getUserId());
                userDetail.setRestAmount(user.getRestAmount().add(sellAmount));
                userDetail.setTotalAmount(user.getTotalAmount().subtract(cost));
                userDetailService.updateUser(userDetail);
                //给用户发通知
                String inform = "您好，您已成功卖出【活期产品】：" + split[1] + "。" + "-" + Integer.valueOf(split[2]) + "-" + "y";
                orderMessage.sendMessage("pay.inform.user", "pay_inform_user", inform);
                //向卖出表添加数据
                AddSellRecord addSellRecord = new AddSellRecord();
                addSellRecord.setUserId(Integer.valueOf(split[2]));
                addSellRecord.setDealTime(AppUtils.getNowTimeStr());
                addSellRecord.setDealPrice(dealMoney);
                addSellRecord.setUserIncome(sellAmount);
                addSellRecord.setDealCharge(cost);
                addSellRecord.setProductType(split[5]);
                addSellRecord.execute();
                //向平台收益表添加数据
                AddEarnings addEarnings = new AddEarnings();
                addEarnings.setDealTime(AppUtils.getNowTimeStr());
                addEarnings.setDealType(AddEarnings.SELL);
                addEarnings.setUserId(Integer.valueOf(split[2]));
                addEarnings.setDealPrice(dealMoney);
                addEarnings.setDealCharge(cost);
                addEarnings.setProductType(split[5]);
                addEarnings.execute();
            }
            // 确认接收，并处理该消息：
            channel.basicAck(tag, false);
            // 发起 HTTP 请求: http://可靠消息服务/message/{}/received"
            orderMessage.receivedMessage(messageId);
        } catch (RuntimeException e) {
            // 执行本地业务出错，拒绝消息，要求 RabbitMQ 从队列中删除。
            // 等待发送者的定时器下次再发送一次。
            channel.basicReject(tag, false);
            throw new NullPointerException();
        }
    }

}
